/*
 * @Author: xiaosihan 
 * @Date: 2024-06-17 02:37:46 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-06-18 20:23:31
 */

import { AdditiveBlending, Color, ShaderChunk, ShaderMaterial } from "three";
import threeLoader from "../threeLoader";
import { ONE_SPRITE_ROW_LENGTH } from "./FireGromtry";

// 火焰粒子材质
export default class FireMaterial extends ShaderMaterial {

    constructor() {
        super();
    }

    // 材质参数
    uniforms = {
        color: { value: new Color() },
        size: { value: 0.0 },
        map: { value: threeLoader.getTexture("") },
        time: { value: 0.0 },
        heightOfNearPlane: { value: 0.0 }
    };

    // 顶点着色器
    vertexShader = `
        ${ShaderChunk.common}
        ${ShaderChunk.logdepthbuf_pars_vertex}
        attribute float random;
        attribute float sprite;
        uniform float time;
        uniform float size;
        uniform float heightOfNearPlane;
        
        varying float vSprite;
        varying float vOpacity;
        
        float quadraticIn( float t ) {
            float tt = t * t;
            return tt * tt;
        }
        
        void main() {
            float progress = fract( time + ( 2.0 * random - 1.0 ) );
            float progressNeg = 1.0 - progress;
            float ease = quadraticIn( progress );
            float influence = sin( PI * ease );
            
            vec3 newPosition = position * vec3( 1.0, ease, 1.0 );
            gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
            gl_PointSize = ( heightOfNearPlane * size ) / gl_Position.w;

            vOpacity = min( influence * 100.0, 1.0 ) * progressNeg;
            vSprite = sprite;
            ${ShaderChunk.logdepthbuf_vertex}
        }
    `;

    //片元着色器
    fragmentShader = `
        ${ShaderChunk.logdepthbuf_pars_fragment}
        uniform vec3 color;
        uniform sampler2D map;
        
        varying float vSprite;
        varying float vOpacity;
        
        void main() {
            vec2 texCoord = vec2(
                gl_PointCoord.x * ${ONE_SPRITE_ROW_LENGTH}  + vSprite,
                gl_PointCoord.y
            );
            // gl_FragColor = vec4( texture2D( map, texCoord ).xyz * color * vOpacity, 1.0 );
            vec4 textureColor = texture2D( map, texCoord );
            float colorMax = max(max(textureColor.x, textureColor.y),textureColor.z);
            vec4 newTextureColor = vec4( textureColor.xyz * (100.0) , colorMax);
            gl_FragColor = newTextureColor * vec4(color,1.0) * vOpacity;
            ${ShaderChunk.logdepthbuf_fragment}
        }
    `

    blending = AdditiveBlending
    depthTest = true
    depthWrite = false;
    transparent = true
    fog = false


}